﻿using System;
using System.Windows;
using System.Collections;
using System.Collections.Generic;

using System.ComponentModel;

namespace ETRoboConTrakingSystem
{
    public enum SwitchBoxButtonType
    {
        START,
        RESET,
        GOAL_IN,
        GOAL_OUT,
        RETIRE_IN,
        RETIRE_OUT,
    }

    /// <summary>
    /// スイッチボックスのボタン押下を通知するためのデレゲータ
    /// </summary>
    /// <param name="buttonType">押下されたボタンの種別</param>
    /// <param name="tick">ボタン押下の時間</param>
    public delegate void SwitchBoxButtonStatusChanged(SwitchBoxButtonType buttonType, Int64 tick);


    /// <summary>
    /// SwitchBoxを利用する側が実装する。
    /// </summary>
    public interface ISwitchBoxClient
    {
        void SetDevice(ISwitchBoxDevice device);
        event SwitchBoxLEDStatus OnSwitchBoxLEDStatusChanged;
    }

    /// <summary>
    /// スイッチボックスにLED表示の変更を指示するためのデレゲータ
    /// </summary>
    /// <param name="on">trueならば点灯、falseならば消灯</param>
    public delegate void SwitchBoxLEDStatus(bool start, bool reset, bool goalIn, bool retireIn,bool goalOut, bool retierOut);

    /// <summary>
    /// SwitchBoxサービスを提供する側が実装する。
    /// </summary>
    public interface ISwitchBoxDevice
    {
        void Start(ISwitchBoxClient client);
        void Stop();

        event SwitchBoxButtonStatusChanged OnButtonStatusChanged;
    }

    /// <summary>
    /// SwitchBoxDevice実装の種別を識別するためのメタデータ
    /// </summary>
    public interface ISwitchBoxAwareness
    {
        string ConnectionType { get; set; }
    }




    public class RoundInfo : INotifyPropertyChanged
    {
        private int _roundNo;
        private int? _turnNo;
        private string _gameName;

        public int RoundNo
        {
            get { return _roundNo; }
            set
            {
                _roundNo = value;
                OnPropertyChanged("RoundNo");
            }
        }

        public int? TurnNo
        {
            get { return _turnNo; }
            set
            {
                _turnNo = value;
                OnPropertyChanged("TurnNo");
            }
        }

        public string GameName
        {
            get { return _gameName; }
            set
            {
                _gameName = value;
                OnPropertyChanged("GameName");
            }
        }

        public RoundInfo()
        {
        }

        public event PropertyChangedEventHandler PropertyChanged;

        public void OnPropertyChanged(string name)
        {
            PropertyChangedEventHandler handler = PropertyChanged;
            if (handler != null)
            {
                handler(this, new PropertyChangedEventArgs(name));
            }
        }
    }

    public class ClearMarkSpec
    {
        public int CanvasTop { get; set; }
        public int CanvasLeft { get; set; }
        public string Key { get; set; }
        public string Name { get; set; }
    }

    public class RunnerInfo : INotifyPropertyChanged
    {
        private int? _bib;
        private string _teamName;
        private string _runTime;
        private string _point;
        private string _previousRound;

        public int? Bib
        {
            get { return _bib; }
            set
            {
                _bib = value;
                OnPropertyChanged("Bib");
            }
        }
        public string TeamName
        {
            get { return _teamName; }
            set
            {
                _teamName = value;
                OnPropertyChanged("TeamName");
            }
        }
        public string RunTime
        {
            get { return _runTime; }
            set
            {
                _runTime = value;
                OnPropertyChanged("RunTime");
            }
        }
        public string Point
        {
            get { return _point; }
            set
            {
                _point = value;
                OnPropertyChanged("Point");
            }
        }

        public string PreviousRoundStatus
        {
            get { return _previousRound; }
            set
            {
                _previousRound = value;
                OnPropertyChanged("PreiviousRoundStatus");
            }
        }

        public RunnerInfo()
        {
        }


        public event PropertyChangedEventHandler PropertyChanged;
        public void OnPropertyChanged(string name)
        {
            PropertyChangedEventHandler handler = PropertyChanged;
            if (handler != null)
            {
                handler(this, new PropertyChangedEventArgs(name));
            }
        }

    }

    public interface ITimerCounter
    {
        int CurrentTime { get; set; }
        void SetCurrentCount(int current);
        void Start();
        void Stop();

        void AlertStart();
        void AlertStop();
        void ResetCounter();
    }

    public interface IRunnerStatus
    {
        RunnerInfo CurrentRunner { get; }
        ITimerCounter RunnerTimerCounter { get; set; }
        IDifficultPointStatus DifficultPointStatus { get; }

        void HiddenRunnerStatus();
        void ShowCleardMark(string key, int level, bool state);
        void BuildClearMarks(List<ClearMarkSpec> clearMarkSpecs);
        void ResetClearedMarks();

        void ShowRunnerStatus(string status);
        void ResetRunnerTimerCounter();
    }

    public interface IDifficultPointStatus
    {
        void ShowImage(int index);
        void ResetImage();
        void LoadStatusItem(int index, object item);
    }

    public interface IRaceTrackingPresentation
    {
        RoundInfo CurrentRoundInfo { get; }
        RunnerInfo CurrentInCourseRunnerInfo { get; }
        RunnerInfo CurrentOutCourseRunnerInfo { get; }
        IRunnerStatus InCourseRunnerStatus { get; }
        IRunnerStatus OutCourseRunnerStatus { get; }
        ITimerCounter MainTimerCounter { get; }
        void ResetPresentation();
        void ResetTimerCounter();
        void ShowTeamNameAnimation(String inTeamName, String outTeamName, int turn, int round);
        void UpdateInCourseRunnerTime(string time);
        void UpdateOutCOurseRunnerTime(string time);

        void NotifyCommands(IDictionary<string, string> commands);
    }

}
